package org.aplombh.java.awcing.basic.graph.udg;

import java.util.Arrays;
import java.util.Scanner;

import static java.lang.Math.max;
import static java.lang.Math.min;

/**
 *给定一颗树，树中包含 n 个结点（编号 1∼n）和 n−1 条无向边。
 *
 * 请你找到树的重心，并输出将重心删除后，剩余各个连通块中点数的最大值。
 *
 * 重心定义：重心是指树中的一个结点，如果将这个点删除后，剩余各个连通块中点数的最大值最小，那么这个节点被称为树的重心。
 *
 * 输入格式
 * 第一行包含整数 n，表示树的结点数。
 *
 * 接下来 n−1 行，每行包含两个整数 a 和 b，表示点 a 和点 b 之间存在一条边。
 *
 * 输出格式
 * 输出一个整数 m，表示将重心删除后，剩余各个连通块中点数的最大值。
 *
 * 数据范围
 * 1≤n≤105
 * 输入样例
 * 9
 * 1 2
 * 1 7
 * 1 4
 * 2 8
 * 2 5
 * 4 3
 * 3 9
 * 4 6
 * 输出样例：
 * 4
 */
public class TheCenterGravityOfTree_846 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        DeepFirstSearch deep = new DeepFirstSearch(n);

        for (int i = 0; i < n - 1; i++) {
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            deep.add(a, b);
            deep.add(b, a);
        }
        deep.dfs(1);
        System.out.println(deep.ans);

    }
}

class DeepFirstSearch {
    public static final int N = 100010;
    public static final int M = N * 2;

    // 存储n个链表的表头 Store n linked list headers
    int[] h = new int[N];

    // 所有的边 all edge
    int[] e = new int[M];

    // 存储每个点的next指针 Stores the next pointer to each point
    int[] ne = new int[M];

    // 存储标记，是否被使用过
    boolean[] st = new boolean[N];

    // 数据节点的指针
    int idx;

    //
    int ans = N;
    int n;

    DeepFirstSearch(int n) {
        this.n = n;
        Arrays.fill(h, -1);
    }

    // 在a和b之间连线  -> 在a所在的单链表中插入b Wire between a and b -> Insert b into a's single linked list
    void add(int a, int b) {
        // 存储b节点 Storage b node
        e[idx] = b;
        // 将b节点的next指针指向a所在的单链表的头节点 Point b's next pointer to the head of a's single linked list
        ne[idx] = h[a];
        // 将a所在的单链表的头节点指向b Point the head node of a's singly linked list to b
        h[a] = idx++;
    }

    //以u为根的子树中点的数量
    int dfs(int u) {
        st[u] = true; //标记一下，已经被搜过了 Mark it. It's already been searched

        // sum为以u为根的子树中的点的个数，初始化时将根节点算上 Sum is the number of points in the subtree rooted in u, and the root node is counted during initialization
        // res为节点数最多的子树的节点数 Res is the number of nodes in the subtree with the largest number of nodes
        int sum = 1, res = 0;

        // 遍历u所在的单链表 Walk through the singly linked list where u is
        for (int i = h[u]; i != -1; i = ne[i]) {
            int j = e[i];
            if (!st[j]) {
                // 未访问过，并且返回以j为根的子树中点的数量
                int s = dfs(j);

                // 取res（所有子树中节点最多的节点的节点数）和s（当前节点为根的子树的节点数）重的最大值
                res = max(res, s);
                // 节点总数为所有子节点为根的子树中点的个数的和
                sum += s;
            }
        }
        // n-sum 为父节点所在树的点的个数 n-sum is the number of points in the tree where the parent node resides
        res = max(res, n - sum);

        // res是u为根的子树中节点最多的点
        // res和其他节点为根的节点比较，取较小值
        ans = min(ans, res);

        // 返回以u为根的子树中的点的数量 Returns the number of points in the subtree rooted in u
        return sum;
    }
}